home *** CD-ROM | disk | FTP | other *** search
-
- IDT 'ADPCM'
- OPTION XREF
- *;
- *;**********************************************************
- *;**********************************************************
- *; This is the source module for a full duplex 32Kbps ADPCM
- *; system. This system is modelled after the CCITT standard
- *; but is not identically bit compatible and does not
- *; include synchronous coding adjustment in the receiver
- *; (this could be added). The loading on the system
- *; averages about 98%. The system reads samples on an
- *; interrupt basis from a mu-law codec (port 1) every 125
- *; microsec and outputs an ADPCM sample to port 4. During
- *; each interrupt, the system will also read a 4 bit ADPCM
- *; sample from port 3 and output an 8 bit mu-law PCM sample
- *; to port 2.
- *;
- *;**********************************************************
- *;**********************************************************
- PAGE
- *;
- *; System I/O channel assignments
- *;
- ADC EQU 1
- DAC EQU 2
- IN32K EQU 3
- OUT32K EQU 4
- *;
- PAGE
- *;**********************************************************
- AORG 0
- *;
- B RESET
- *;
- *;**********************************************************
- *; INTERRUPT HANDLING ROUTINE -- SYSTEM HANDLES CODEC
- *; INTERRUPTS ON A SAMPLE BY SAMPLE BASIS. DURING
- *; EACH SAMPLE PERIOD BOTH A RECEIVE AND A TRANSMIT CYCLE
- *; ARE EXECUTED.
- *;*************************************************************************
- *;
- *; first execute code to transmit a 4-bit adpcm sample
- *;
- INTRPT IN SAMPLE,ADC ; Get sample
- *;
- *; patch to stop simulation
- *;
- LAC SAMPLE
- SUB ONE,8
- STPSIM BGEZ STPSIM
- *;
- LAC SAMPLE ; linearize
- XOR M255
- ADD CODEAD
- TBLR SAMPLE
- *;
- PAGE
- *;
- *;*********************************************************
- *; SIGDIF
- *;
- *; COMPUTE SCALE FACTOR AND BOTH PARTIAL AND FULL SIGNAL
- *; ESTIMATE FROM PREVIOUS SAMPLES DATA -- THEN COMPUTE
- *; DIFFERENCE SIGNAL
- *;*********************************************************
- *;
- *; compute SEZ-- partial signal estimate
- *;
- *; SEZ(k) = B1(k-1)*DQ(k-1) + ... + B6(k-1)*DQ(k-6)
- *;
- SIGDIF ZAC
- LT DQ5
- MPY B6
- LTD DQ4
- MPY B5
- LTD DQ3
- MPY B4
- LTD DQ2
- MPY B3
- LTD DQ1
- MPY B2
- LTD DQ
- MPY B1
- APAC
- *;
- *; shift left by 1 to adjust decimal point
- *;
- SACL TEMP1
- SACH TEMP2
- ADDH TEMP2
- ADDS TEMP1
- SACH SEZ,1
- *;
- *; now compute signal estimate as
- *;
- *; A1(k-1)*SR(k-1) + A2(k-1)*SR(k-2) + SEZ(k)
- *;
- GETSE LAC SEZ,14
- LT SR1
- MPY A2
- LTD SR
- MPY A1
- APAC
- *;
- *; shift left by 1 to adjust decimal point
- *;
- SACL TEMP1
- SACH TEMP2
- ADDH TEMP2
- ADDS TEMP1
- SACH SE,1
- *;
- *; limit speed control parameter: AL===> 1.Q6
- *;
- *; APP : 2.Q8 AL: Q6
- *;
- *; AL = 1 (64) if APP > 1 (256)
- *; AL = APP if APP <= 1
- *;
- LIMA LAC ONE,6
- SACL AL
- LAC APP
- SUB ONE,8
- BGEZ MIX ;APP >= 256
- LAC APP,14
- SACH AL ;APP < 256
- *;
- *; form linear combination of fast and slow scale factors
- *;
- *; Y(k) = (1-AL(k))*YL(k-1) + AL(k)*YU(k-1)
- *;
- MIX LAC YLL,10 ; shift yl right by 6
- SACH TEMP3
- LAC TEMP3
- AND M1023
- ADD YLH,10
- SACL TEMP3 ; low half
- LAC YU
- SUB TEMP3 ; YU-(YLL>>6)
- SACL TEMP3
- ZALH YLH
- ADDS YLL
- LT AL
- MPY TEMP3
- APAC ; YL + AL*(YU-(YLL>>6))
- SACL TEMP3
- SACH TEMP2
- LAC TEMP3,10 ; shift right by 6
- SACH TEMP3
- LAC TEMP3
- AND M1023 ; mask sign extension
- ADD TEMP2,10
- AND M8191
- SACL Y
- LAC Y,14
- SACH TEMP3
- *;
- *; get difference signal: D = SAMPLE - SE
- *;
- LAC SAMPLE ; compute difference sig
- SUB SE
- SACL D
- *;
- *;******************************************************
- *; ADAPTIVE QUANTIZER --- 62 CLOCKS
- *;
- *; input: differenced PCM speech sample--D
- *; scale factor--Y
- *; output: 4-b quantized diff signal--I
- *;******************************************************
- *;
- *; first get log of difference signal
- *;
- AQUAN ABS
- SACL TEMP1
- GETEXP SUB ONE,8 ; binary search to get exponent
- BGEZ C8TO14
- C0TO7 ADD M15,4 ; TEMP1-16 exp = 0-7
- BGEZ C4TO7
- C0TO3 ADD THREE,2 ; TEMP1-4 exp = 0-3
- BGEZ C2TO3
- C0TO1 ADD ONE,1 ; TEMP1-2 exp = 0-1
- BGEZ EXP1
- EXP0 LARK 0,0 ; exp = 0
- LAC TEMP1,7
- B GETMAN ; save exponent and get mantissa
- EXP1 LARK 0,1 ; exp = 1
- LAC TEMP1,6
- B GETMAN
- C2TO3 SUB ONE,2 ; TEMP1-8 exp = 2-3
- BGEZ EXP3
- EXP2 LARK 0,2 ; exp = 2
- LAC TEMP1,5
- B GETMAN
- EXP3 LARK 0,3 ; exp = 3
- LAC TEMP1,4
- B GETMAN
- C4TO7 SUB THREE,4 ; TEMP1-64 exp = 4-7
- BGEZ C6TO7
- C4TO5 ADD ONE,5 ; TEMP1-32 exp = 4-5
- BGEZ EXP5
- EXP4 LARK 0,4 ; exp = 4
- LAC TEMP1,3
- B GETMAN
- EXP5 LARK 0,5 ; exp = 5
- LAC TEMP1,2
- B GETMAN
- C6TO7 SUB ONE,6 ; TEMP1-128 exp = 6-7
- BGEZ EXP7
- EXP6 LARK 0,6 ; exp = 6
- LAC TEMP1,1
- B GETMAN
- EXP7 LARK 0,7 ; exp = 7
- LAC TEMP1
- B GETMAN
- C8TO14 SUB M15,8 ; TEMP1-4096 exp = 8-14
- BGEZ CCTOE
- C8TO11 ADD THREE,10 ;TEMP1-1024 exp = 8-11
- BGEZ CATOB
- C8TO9 ADD ONE,9 ; TEMP1-512 exp = 8-9
- BGEZ EXP9
- EXP8 LARK 0,8 ; exp = 8
- LAC TEMP1,15
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- EXP9 LARK 0,9 ; exp = 9
- LAC TEMP1,14
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- CATOB SUB ONE,10 ; TEMP1-2048 exp = 10-11
- BGEZ EXP11
- EXP10 LARK 0,10 ; exp = 10
- LAC TEMP1,13
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- EXP11 LARK 0,11 ; exp = 11
- LAC TEMP1,12
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- CCTOE SUB THREE,12 ;TEMP1-16384 exp = 12-14
- BGEZ EXP14
- CCTOD ADD ONE,13 ; TEMP1-8192 exp = 13-14
- BGEZ EXP13
- EXP12 LARK 0,12 ; exp = 12
- LAC TEMP1,11
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- EXP13 LARK 0,13 ; exp = 13
- LAC TEMP1,10
- SACH TEMP1
- LAC TEMP1
- B GETMAN
- EXP14 LARK 0,14 ; exp = 14
- LAC TEMP1,9
- SACH TEMP1
- LAC TEMP1
- GETMAN AND M127
- SAR 0,TEMP1
- ADD TEMP1,7
- *;
- *; scale by subtraction
- *;
- SUBTB ADD THREE,11
- SUB TEMP3
- AND M4095
- *;
- *; 4b quantizer
- *;
- *; QUANT TABLE FOR 32KB OUTPUT (OFFSET: 2048)
- *;
- ITAB1 EQU 2041
- ITAB2 EQU 2171
- ITAB3 EQU 2250
- ITAB4 EQU 2309
- ITAB5 EQU 2358
- ITAB6 EQU 2404
- ITAB7 EQU 2453
- *;
- QUAN SUB K2309 ; ITAB4
- BGEZ CI4TO7
- CI0TO3 ADD K138 ; ITAB2 I = 0-3
- BGEZ CI2TO3
- CI0TO1 ADD K130 ; ITAB1 I = 0-1
- BGEZ IEQ1
- IEQ0 LACK 0
- B GETIM
- IEQ1 LACK 1
- B GETIM
- CI2TO3 SUB K79 ; ITAB3 I = 2-3
- BGEZ IEQ3
- IEQ2 LACK 2
- B GETIM
- IEQ3 LACK 3
- B GETIM
- CI4TO7 SUB K95 ; ITAB6 I = 4-7
- BGEZ CI6TO7
- CI5TO6 ADD K46 ; ITAB5 I = 5-6
- BGEZ IEQ5
- IEQ4 LACK 4
- B GETIM
- IEQ5 LACK 5
- B GETIM
- CI6TO7 SUB K49 ; ITAB6 I = 6-7
- BGEZ IEQ7
- IEQ6 LACK 6
- B GETIM
- IEQ7 LACK 7
- GETIM SACL IM
- SACL I
- LAC D
- BGEZ OUTI
- LAC IM
- XOR M15
- SACL I
- OUTI OUT I,OUT32K ; XMITTER OUTPUT
- *;
- *;**********************************************************
- *; INVERSE ADAPTIVE QUANTIZER
- *;
- *; input: 4b quantized samples -- IM
- *; scale factor -- Y
- *; output: reconstructed diff sig -- DQ
- *;**********************************************************
- *;
- *; first convert quantized difference back to log domain
- *;
- IAQUAN LAC IM
- ADD INQTAB ; reconst table
- TBLR TEMP1
- *;
- *; add back scale factor
- *;
- ADDA LAC TEMP1
- ADD TEMP3 ; Y >> 2
- AND M2047
- SACL TEMP2
- *;
- *; now covert to linear domain
- *;
- *;
- ALOG LAC TEMP2,9 ; extract exp
- SACH TEMP1
- LACK 127
- AND TEMP2
- ADD ONE,7 ; 1+x
- SACL TEMP2 ; extract mantissa
- LT TEMP2 ; prepare to shift
- LAC TEMP1
- ADD SHIFT ; look up multiplier
- TBLR TEMP3
- MPY TEMP3
- PAC
- BLZ LEFTSF
- SACH DQ,1 ; right shift--dqmag
- B ADDSGN
- LEFTSF ABS ; left shift
- SACL DQ ; dqmag
- B ADDSGN
- ADDSGN LAC ONE,11
- SACL SDQ
- LAC I ; check sign
- SUB ONE,3
- BLZ QSFA
- ZAC
- SUB DQ
- SACL DQ
- LAC MINUS,11
- SACL SDQ
- *;
- *;***********************************************************************
- *; QUANTIZER SCALE FACTOR ADAPTATION
- *;
- *; input: I : 32KB coded samples
- *; output: YU,YLL: next sample scale factor
- *;***********************************************************************
- *; First compute WI
- *;
- *; input --IM
- *; output--TEMP1 (WI)
- *;
- QSFA LAC WITAB ; get table address and offset
- ADD IM
- TBLR TEMP1 ; lookup WI (Q6)
- *;
- *; Update fast adaptation scale factor -- constant=1/32
- *;
- *; YU(k)=(1-2**-5)*Y(k)+(2**-5)*WI(k)
- *;
- *; input --TEMP1 (WI--- TC 6...Q4)
- *; output--YU (YU---SM 3...-9)
- *;
- FILTD LAC Y,12 ; Y (Q21)
- SUB Y,7 ; Y/32 (Q21)
- ADD TEMP1,12 ; WI/32 (Q21)
- SACH YU,4 ; YU (Q9)
- LAC YU
- AND M8191
- SACL YU
- *;
- *; limit quant scale factor 1.06 <= YU <= 10.0
- *;
- *; input: YU (3...-9)
- *; ouput: YU
- *;
- LIMB SUB K544 ; check lo threshold
- BGEZ CHKHI
- LAC K544
- B STRLIM ; go store limited value
- CHKHI SUB K4576 ; check hi threshold
- BLEZ FILTE ; within limits--continue
- LAC K5120
- STRLIM SACL YU
- *;
- *; Update slow adaptation scale factor -- constant = 1/64
- *;
- *; YL(k) = (1-2**-6)*YL(k-1) + 2**-6 * YU(k)
- *;
- FILTE LAC YLH,6 ; shift yl left by 6
- SACL TEMP1
- LAC YLL,6
- SACL TEMP2
- SACH TEMP3
- LAC TEMP3 ; suppress sign extension
- AND M63
- SACL TEMP3
- ZALH TEMP1
- ADDH TEMP3
- ADDS TEMP2
- SUBH YLH
- SUBS YLL
- ADD YU,6
- SACL TEMP1
- SACH TEMP2 ; result = yl (shifted left by 6)
- LAC TEMP1,10 ; shift result right 6 --> 4.q15
- SACH TEMP1
- LAC TEMP1
- AND M1023 ; mask sign extension
- ADD TEMP2,10
- SACL YLL
- SACH YLH
- LACK 7 ; mask upper 13 bits
- AND YLH
- SACL YLH
- *;
- *;***********************************************************************
- *; ADAPTATION SPEED CONTROL
- *;
- *; input: IM
- *; output: APP
- *;***********************************************************************
- *;
- *; first compute FI function: 5 CLOCKS
- *;
- SPDCRL LAC FITAB ; look-up value of FI function
- ADD IM
- TBLR TEMP1 ; FI*16
- *;
- *; now update short term average of FI
- *;
- *; DMS(k) = (1-2**-5)*DMS(k-1) + 2**-5 * FI(k)
- *;
- FILTA LAC TEMP1,15 ; FI/32 in q24
- ADD DMS,15
- SUB DMS,10 ; DMS/32
- SACH DMS,1
- *;
- *; update long term average of FI
- *;
- *; DML(k) = (1-2**-7)*DML(k-1) + 2**-7 * FI(k)
- *;
- FILTB LAC TEMP1,15 ; FI/128 in q26
- ADD DML,15
- SUB DML,8 ; DML/128
- SACH DML,1
- *;
- *; Compute mag of diff of short and long term
- *; and perform threshold comparison to compute speed
- *; control parameter--low-pass result.
- *;
- *; APP(k) = (1-2**-4)*APP(k-1) + 2**-3 , if y < 3 or
- *; if |DMS-DML| > 2**-3 * DML
- *; else
- *;
- *; APP(k) = (1-2**-4)*APP(k-1)
- *;
- FILTC ZALH APP
- SUB APP,12
- SACH APP ; (1-2**-4)*APP
- LAC Y
- SUB THREE,9
- BLZ ADD18
- ZALH DMS ; DMS (Q25)
- SUB DML,14 ; DMS-DML
- ABS
- SUB DML,11
- BLZ APRED
- ADD18 LAC APP
- ADD ONE,5
- SACL APP ; +1/8 in Q8
- *;
- *;************************************************************
- *; ADAPTIVE PREDICTOR: compute signal estimate from quantized
- *; difference
- *;
- *; input: DQ quantized difference
- *; output: SE signal estimate
- *;************************************************************
- *;
- *; compute reconstructed signal: DQ + SE
- *;
- APRED LAC DQ
- ADD SE
- SACL SR
- *;
- *; compute coefficients of 6th order predictor
- *;
- *; Bi(k) = (1-2**-8)*Bi(k-1)
- *; + 2**-7 * SGN[DQ(k)] * SGN[DQ(k-1)]
- *;
- *; for i = 1...6
- *; and Bi is implicitly limited to +/- 2
- *;
- GETB6 LT SDQ6
- LAC B6,15 ; Q29
- SUB B6,7 ; B6 * 2**-7 (Q29)
- MPY SDQ ; SGN(SDQ)*SGN(SDQ6)*2**-7 (Q29)
- LTD SDQ5
- SACH B6,1 ; 1.Q14
- GETB5 LAC B5,15
- SUB B5,7
- MPY SDQ
- LTD SDQ4
- SACH B5,1
- GETB4 LAC B4,15
- SUB B4,7
- MPY SDQ
- LTD SDQ3
- SACH B4,1
- GETB3 LAC B3,15
- SUB B3,7
- MPY SDQ
- LTD SDQ2
- SACH B3,1
- GETB2 LAC B2,15
- SUB B2,7
- MPY SDQ
- LTD SDQ1
- SACH B2,1
- GETB1 LAC B1,15
- SUB B1,7
- MPY SDQ
- LTD SDQ
- SACH B1,1
- *;
- *; Update coefficients of 2nd order predictor
- *;
- *; First get sign of sum of quantized diff
- *; and partial sig estimate
- *;
- ADDC DMOV PK1 ; PK1==>PK2
- DMOV PK0 ; PK0==>PK1
- LAC ONE,9
- SACL PK0
- LAC SEZ
- ADD DQ
- BGEZ SUMGT0 ; is SEZ+DQ negative?
- LAC MINUS,9
- SACL PK0
- SUMGT0 LT PK0
- *;
- *; now calculate f[A1(k-1)] ==> TEMP3 will get 1/2 F
- *;
- *; = 4*A1 if |A1| <= 1/2
- *; = 2*SGN(A1) if |A1| > 1/2
- *;
- GETF LAC A1,1 ; 2*A1
- SACL TEMP3
- BLZ GETF2
- GETF1 SUB ONE,14
- BLZ GETA1
- LAC ONE,14
- B DONEF
- GETF2 ABS
- SUB ONE,14
- BLZ GETA1
- LAC MINUS,14
- DONEF SACL TEMP3
- *;
- *; A1(k) = (1-2**-8)*A1(k-1)
- *; + (3*2**-8)*SGN[p(k)]*SGN[p(k-1)]
- *;
- GETA1 LAC A1,12
- SUB A1,4
- MPY PK1 ; 3*SGN[p(k-1)*SGN[p(k)]
- APAC
- APAC
- APAC
- SACH A1,4
- PAC ; save sign of SGN[p(k-1)]*SGN[p(k)]
- *;
- *; A2(k) = (1-2**-7)*A2(k-1)
- *; + (2**-7)*{SGN[p(k)]*SGN[(p(k-2)]
- *; - f[A1(k-1)]*SGN[p(k)]*SGN[p(k-1)]}
- *;
- GETA2 BGEZ SUBF ; if sign + --> subtract F
- ZAC ; else negate F and subtract
- SUB TEMP3
- SACL TEMP3
- *;
- SUBF LAC A2,12
- SUB A2,5
- MPY PK2
- APAC
- APAC
- SUB TEMP3,6
- SACH A2,4
- *;
- *; now limit A2 to +/- .75 and prevent overflow
- *;
- LIMC LAC A2
- ABS
- SUB THREE,12 ; |value| must be < .75
- BLEZ LIMD
- LAC A2
- BGEZ SATPOS
- SATNEG LAC MINUS3,12 ; -.75
- B DONEG
- SATPOS LAC THREE,12
- DONEG SACL A2
- *;
- *; limit A1 to +/- 1-2**-4 - A2
- *;
- LIMD LAC M15,10
- SUB A2
- SACL TEMP1 ; 1-2**-4-A2P
- LAC A1
- ABS
- SUB TEMP1
- BLEZ GET32K ; A1 <= LIMIT
- LAC A1
- BGEZ A1LIM
- ZAC
- SUB TEMP1
- SACL TEMP1
- A1LIM LAC TEMP1
- SACL A1